package com.gwtjs.icustom.controller.manager;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.gwtjs.icustom.entity.ResultWrapper;
import com.gwtjs.icustom.exception.SqliteException;
import com.gwtjs.icustom.mapper.AmbariInstallInfoMapper;
import com.gwtjs.icustom.mapper.ServerHostMapper;
import com.gwtjs.icustom.pojo.AmbariInstallInfo;
import com.gwtjs.icustom.pojo.ServerHost;
import com.gwtjs.icustom.utils.ImportExcelUtil;
import com.gwtjs.icustom.utils.ShellUtil;

@RestController
@RequestMapping("/host")
public class ManagerServerHostController {

	private final static Logger logger = LoggerFactory.getLogger(ManagerServerHostController.class);

	@Autowired
	private ServerHostMapper serverHostMapper;
	@Autowired
	private AmbariInstallInfoMapper ambariInstallInfoMapper;
	
	@Resource
	private ImportExcelUtil excelUtils;

	/**
     * <h2>上传主机excel</h2>
     * <code>
     * </code>
     * @param excelFile
     * @return
     * @throws Exception
     */
	@PostMapping("/upload")
	public ResultWrapper upload(@RequestParam("excelFile") MultipartFile excelFile) throws Exception {
		List<ServerHost> hosts = new ArrayList<ServerHost>();
		if (excelFile.isEmpty()) {
			return ResultWrapper.constructErrorResult("上传失败", "文件夹为空，重新上传");
		} 
		String fileName = excelFile.getOriginalFilename();
		InputStream is = excelFile.getInputStream();
		Workbook workbook = excelUtils.getWorkbook(fileName, is);
		hosts = excelUtils.excelToServerHostObject(workbook);
		try {
			this.batchAddHost(hosts);
		} catch (Exception e) {
			String msg = e.getMessage();
			e.printStackTrace();
			logger.info("添加主机信息异常: {}\n",msg);
			boolean flag = msg.contains("SQLITE_CONSTRAINT_UNIQUE");
			if(flag) {
				throw new SqliteException("主机IP重复。","上传失败");
			}else {//其它未知异常就抛出
				throw e;
			}
			
		}

		return this.updateHostname(hosts);
	}

	@RequestMapping("/list")
	public List<ServerHost> queryHostList() throws Exception {

		List<ServerHost> list = null;
		try {
			list = serverHostMapper.queryHostList();
		} catch (Exception e) {
			String status = e.getMessage().concat("SQLITE_ERROR");
			logger.info("\nstatus:{} " ,status);
			e.printStackTrace();
		}
		return list;
	}
	
	@RequestMapping("/list/{type}")
	public ResultWrapper queryHostList(@PathVariable("type") String type) throws Exception {

		List<ServerHost> list = null;
		try {
			list = serverHostMapper.queryHostList();
		} catch (Exception e) {
			String status = e.getMessage().concat("SQLITE_ERROR");
			logger.info("\nstatus:{} " ,status);
			e.printStackTrace();
		}
		Integer maxId = ambariInstallInfoMapper.queryInfoMaxId();
		AmbariInstallInfo obj=ambariInstallInfoMapper.queryInstallInfoById(maxId);
		ResultWrapper wrap = new ResultWrapper(obj,list);
		return wrap;
	}

	/**
	 * <h2>批量(伪)新增主机</h2> <code>
	 * [
	  {"id":1,"hostIp":"192.168.152.100","hostName":"hdp123","hostPort":"22","account":"root","password":"rootroot123"},
	  {"id":2,"hostIp":"192.168.152.101","hostName":"hdp3","hostPort":"22","account":"root","password":"rootroot123"}
	  ]
	 * </code>
	 * 
	 * @param records
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/add")
	public ResultWrapper addHost(@RequestBody ServerHost host) throws Exception {
		logger.info("\nrecords:{} " ,host);
		
		serverHostMapper.addHost(host);
		//this.updateHostname(records);
		return ResultWrapper.constructSuccessResult(host);
	}

	/**
	 * <h2>批量(伪)新增主机</h2> <code>
	 * [
	  {"id":1,"hostIp":"192.168.152.100","hostName":"hdp123","hostPort":"22","account":"root","password":"rootroot123"},
	  {"id":2,"hostIp":"192.168.152.101","hostName":"hdp3","hostPort":"22","account":"root","password":"rootroot123"}
	  ]
	 * </code>
	 * 
	 * @param records
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/batchAddHost")
	public ResultWrapper batchAddHost(@RequestParam List<ServerHost> records) throws Exception {
		logger.info("\nrecords:{} " ,records);
		/*for (ServerHost host : records) {
			serverHostMapper.addHost(host);
		}*/
		serverHostMapper.addHosts(records);
		return ResultWrapper.constructSuccessResult(records);
	}

	/**
	 * <h2>批量删除主机</h2> <code>
	 * [{"id":1},{"id":2}]
	 * </code>
	 * 
	 * @param records
	 * @return
	 * @throws Exception
	 */
	@DeleteMapping("/del")
	public ResultWrapper batchDeleteHosts(@RequestBody List<ServerHost> records) throws Exception {
		logger.info("\nrecords:{} " ,records);
		serverHostMapper.deleteHosts(records);
		return ResultWrapper.constructSuccessResult(records);
	}

	/**
	 * <h2>批量删除主机</h2> <code>
	 * [{"id":1},{"id":2}]
	 * </code>
	 * 
	 * @param records
	 * @return
	 * @throws Exception
	 */
	@DeleteMapping("/dele")
	public ResultWrapper batchDeleteHost(@RequestBody List<Integer> ids) throws Exception {
		List<ServerHost> records = new ArrayList<>();
		ServerHost host = null;
		logger.info("\nids:{} " ,ids);
		for (Integer id : ids) {
			host = new ServerHost();
			host.setId(id);
			records.add(host);
		}
		
		return this.batchDeleteHosts(records);
	}

	@PutMapping("/update")
	public ResultWrapper updateHosts(@RequestBody List<ServerHost> records) {
		System.out.println("records: " + records.toString());
		for (ServerHost host : records) {
			serverHostMapper.updateHost(host);
		}
		return ResultWrapper.constructSuccessResult(records);
	}

	/**
	 * 更新主机名
	 * <code>
	 * http://192.168.152.101:8080/host/update/hostname
	 * [
	  {"id":1,"hostIp":"192.168.152.100","hostName":"hdp123","hostPort":"22","account":"root","password":"rootroot123"},
	  {"id":2,"hostIp":"192.168.152.101","hostName":"hdp3","hostPort":"22","account":"root","password":"rootroot123"}
	  ]
	 * </code>
	 * @param records
	 * @return
	 */
	@PutMapping("/update/hostname")
	public ResultWrapper updateHostname(@RequestBody List<ServerHost> records) {
		System.out.println("records: " + records.toString());
		//先执行shell,成功后才能写入数据库 ssh 
		String cmd = "ip addr";
		
		ShellUtil execute = null;
		for (ServerHost host : records) {
			cmd = "hostnamectl set-hostname "+host.getHostName();
			execute = new ShellUtil(host.getHostIp(), host.getAccount(), host.getPassword(), host.getHostPort());
			// 执行命令
			String result = execute.executeForResult(cmd);
			serverHostMapper.updateHostname(host);
			logger.info("\n更新主机名 cmd ：{}\n{}\n" , cmd,result);
			execute.close();
    			
		}
		return ResultWrapper.constructSuccessResult(records);
	}

	@RequestMapping("/get/{id}")
	public ServerHost queryHostList(@PathVariable("id") Integer id) throws Exception {
		return serverHostMapper.queryHostById(id);
	}
	
	/**
	 * <h2>按IP查询主机</h2>
	 * @param hostIp
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/gethost/{hostIp}")
	public ServerHost queryServer(@PathVariable("hostIp") String hostIp) throws Exception {
		return serverHostMapper.queryHostByIp(hostIp);
	}

}
